package com.service.tm;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.common.DateUtils;
import com.common.StringUtils;
import com.common.easyui.EasyuiUtils;
import com.common.http.HttpResult;
import com.common.http.HttpStatus;
import com.common.model.Global;
import com.common.spring.SpringMvcUtils;
import com.dao.tm.PlanDao;
import com.dao.tm.StoreDao;
import com.model.external.sap.SapStoreModel;
import com.model.sys.SysUser;
import com.model.tm.PlanModel;
import com.model.tm.StoreModel;
import com.service.external.sap.CallSapRfcService;

@Service("tmStoreService")
public class StoreService {
	static final Logger logger = LoggerFactory.getLogger(StoreService.class);

	@Autowired
	StoreDao storeDao;
	@Autowired
	CallSapRfcService callSapRfcService;
	@Autowired
	PlanService planService;
	@Autowired
	PlanDao planDao;

	// 获取实时库存
	public HttpResult getStoreFromSap(String stoDate) {
		Map<String, PlanModel> todayMap = groupPlan(stoDate);
		Map<String, PlanModel> tomorowMap = groupPlan(DateUtils.addDays(stoDate, 1));
		Map<String, PlanModel> afterMap = groupPlan(DateUtils.addDays(stoDate, 2));
		Map<String, PlanModel> plan4 = groupPlan(DateUtils.addDays(stoDate, 3));
		Map<String, PlanModel> plan5 = groupPlan(DateUtils.addDays(stoDate, 4));
		Map<String, PlanModel> plan6 = groupPlan(DateUtils.addDays(stoDate, 5));
		Map<String, PlanModel> plan7 = groupPlan(DateUtils.addDays(stoDate, 6));
		Map<String, PlanModel> plan8 = groupPlan(DateUtils.addDays(stoDate, 7));
		Map<String, PlanModel> plan9 = groupPlan(DateUtils.addDays(stoDate, 8));
		Map<String, PlanModel> plan10 = groupPlan(DateUtils.addDays(stoDate, 9));
		Map<String, PlanModel> plan11 = groupPlan(DateUtils.addDays(stoDate, 10));

		Map<String, PlanModel> planMap = groupPlanOccupy();
		stoDate = stoDate.replaceAll("-", "");
		HttpResult goodHttpResult = callSapRfcService.getStore(stoDate);
		if (goodHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
			return HttpResult.error(goodHttpResult.getMsg());
		}
		List<SapStoreModel> receiveList = JSONObject.parseArray(goodHttpResult.getData().toString(),
				SapStoreModel.class);
//		storeDao.deleteAll();
		String mapName = "";
		for (SapStoreModel sapStoreModel : receiveList) {
			StoreModel storeModel = new StoreModel();
			storeModel.setStoFac(sapStoreModel.getWerks());
			storeModel.setStoAddress(sapStoreModel.getLgort());
			storeModel.setStoAddressDetail(sapStoreModel.getLgobe());
			storeModel.setStoMmCode(sapStoreModel.getMatnr());
			storeModel.setStoMmDetail(sapStoreModel.getMaktx());
			// 累计
			storeModel.setStoTodayStore(sapStoreModel.getSto1());
			storeModel.setStoOccupy(sapStoreModel.getLfimg());
			mapName = storeModel.getStoMmCode() + "-" + storeModel.getStoFac() + "-" + storeModel.getStoAddress();
			if (planMap.get(mapName) != null) {
				storeModel.setStoPlanOccupy(planMap.get(mapName).getProNum());
			}
			// 今日
			storeModel.setStoTodayOccupy(sapStoreModel.getLfimg1());
			storeModel.setStoTodayPlan(new BigDecimal(0));
			if (todayMap.get(mapName) != null) {
				storeModel.setStoTodayPlan(todayMap.get(mapName).getProNum());
			}
			storeModel.setStoTodayProduct(sapStoreModel.getJryj1());
			storeModel.setStoTodayResidue(storeModel.getStoTodayStore()
					.subtract(storeModel.getStoTodayPlan() == null ? BigDecimal.ZERO : storeModel.getStoTodayPlan())
					.subtract(storeModel.getStoOccupy() == null ? BigDecimal.ZERO : storeModel.getStoOccupy()));
			// 明日
			storeModel.setStoTomorowPlan(new BigDecimal(0));
			if (tomorowMap.get(mapName) != null) {
				storeModel.setStoTomorowPlan(tomorowMap.get(mapName).getProNum());
			}
			storeModel.setStoTomorowProduct(sapStoreModel.getJryj2());
			storeModel.setStoTomorowOccupy(sapStoreModel.getLfimg2());
			storeModel.setStoTomorowStore(storeModel.getStoTodayResidue().add(sapStoreModel.getJryj2()));
			storeModel.setStoTomorowResidue(storeModel.getStoTomorowStore().subtract(storeModel.getStoTomorowPlan()));
			// 后日
			storeModel.setStoAcquiredPlan(new BigDecimal(0));
			if (afterMap.get(mapName) != null) {
				storeModel.setStoAcquiredPlan(afterMap.get(mapName).getProNum());
			}
			storeModel.setStoAcquiredProduct(sapStoreModel.getJryj3());
			storeModel.setStoAcquiredOccupy(sapStoreModel.getLfimg3());
			storeModel.setStoAcquiredStore(storeModel.getStoTomorowResidue().add(sapStoreModel.getJryj3()));
			storeModel
					.setStoAcquiredResidue(storeModel.getStoAcquiredStore().subtract(storeModel.getStoAcquiredPlan()));


			storeModel.setStoPlan4(new BigDecimal(0));
			if (plan4.get(mapName) != null) {
				storeModel.setStoPlan4(plan4.get(mapName).getProNum());
			}
			storeModel.setStoPlan5(new BigDecimal(0));
			if (plan5.get(mapName) != null) {
				storeModel.setStoPlan5(plan5.get(mapName).getProNum());
			}
			storeModel.setStoPlan6(new BigDecimal(0));
			if (plan6.get(mapName) != null) {
				storeModel.setStoPlan6(plan6.get(mapName).getProNum());
			}
			storeModel.setStoPlan7(new BigDecimal(0));
			if (plan7.get(mapName) != null) {
				storeModel.setStoPlan7(plan7.get(mapName).getProNum());
			}
			storeModel.setStoPlan8(new BigDecimal(0));
			if (plan8.get(mapName) != null) {
				storeModel.setStoPlan8(plan8.get(mapName).getProNum());
			}
			storeModel.setStoPlan9(new BigDecimal(0));
			if (plan9.get(mapName) != null) {
				storeModel.setStoPlan9(plan9.get(mapName).getProNum());
			}
			storeModel.setStoPlan10(new BigDecimal(0));
			if (plan10.get(mapName) != null) {
				storeModel.setStoPlan10(plan10.get(mapName).getProNum());
			}
			storeModel.setStoPlan11(new BigDecimal(0));
			if (plan11.get(mapName) != null) {
				storeModel.setStoPlan11(plan11.get(mapName).getProNum());
			}

			storeModel.setStoProduct4(sapStoreModel.getJryj4());
			storeModel.setStoProduct5(sapStoreModel.getJryj5());
			storeModel.setStoProduct6(sapStoreModel.getJryj6());
			storeModel.setStoProduct7(sapStoreModel.getJryj7());
			storeModel.setStoProduct8(sapStoreModel.getJryj8());
			storeModel.setStoProduct9(sapStoreModel.getJryj9());
			storeModel.setStoProduct10(sapStoreModel.getJryj10());
			storeModel.setStoProduct11(sapStoreModel.getJryj11());

			storeModel.setStoResidue4(storeModel.getStoAcquiredResidue().add(sapStoreModel.getJryj4())
					.subtract(storeModel.getStoAcquiredPlan()));
			storeModel.setStoResidue5(storeModel.getStoResidue4().add(sapStoreModel.getJryj5())
					.subtract(storeModel.getStoPlan5()));
			storeModel.setStoResidue6(storeModel.getStoResidue5().add(sapStoreModel.getJryj6())
					.subtract(storeModel.getStoPlan6()));
			storeModel.setStoResidue7(storeModel.getStoResidue6().add(sapStoreModel.getJryj7())
					.subtract(storeModel.getStoPlan7()));
			storeModel.setStoResidue8(storeModel.getStoResidue7().add(sapStoreModel.getJryj8())
					.subtract(storeModel.getStoPlan8()));
			storeModel.setStoResidue9(storeModel.getStoResidue8().add(sapStoreModel.getJryj9())
					.subtract(storeModel.getStoPlan9()));
			storeModel.setStoResidue10(storeModel.getStoResidue9().add(sapStoreModel.getJryj10())
					.subtract(storeModel.getStoPlan10()));
			storeModel.setStoResidue11(storeModel.getStoResidue10().add(sapStoreModel.getJryj11())
					.subtract(storeModel.getStoPlan11()));
			
			if (storeDao.update(storeModel) == 0) {
				storeDao.insert(storeModel);
			}
		}

		HttpResult httpResult = new HttpResult();
		httpResult.setMsg("刷新成功!");
		return httpResult;
	}

	// 获取实时库存
	public HttpResult getSelectRowFromSap(String stoDate, StoreModel storeModels) {
		Map<String, PlanModel> todayMap = groupPlan(stoDate);
		Map<String, PlanModel> tomorowMap = groupPlan(DateUtils.addDays(stoDate, 1));
		Map<String, PlanModel> afterMap = groupPlan(DateUtils.addDays(stoDate, 2));
		Map<String, PlanModel> planMap = groupPlanOccupy();
		stoDate = stoDate.replaceAll("-", "");
		HttpResult goodHttpResult = callSapRfcService.getStore(stoDate);
		if (goodHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
			return HttpResult.error(goodHttpResult.getMsg());
		}
		List<SapStoreModel> receiveList = JSONObject.parseArray(goodHttpResult.getData().toString(),
				SapStoreModel.class);

		String mapName = "";
		for (SapStoreModel sapStoreModel : receiveList) {
			if (!sapStoreModel.getWerks().equals(storeModels.getStoFac())
					|| !sapStoreModel.getLgort().equals(storeModels.getStoAddress())
					|| !sapStoreModel.getMatnr().equals(storeModels.getStoMmCode())) {
				continue;
			}
			StoreModel storeModel = new StoreModel();
			storeModel.setStoFac(sapStoreModel.getWerks());
			storeModel.setStoAddress(sapStoreModel.getLgort());
			storeModel.setStoAddressDetail(sapStoreModel.getLgobe());
			storeModel.setStoMmCode(sapStoreModel.getMatnr());
			storeModel.setStoMmDetail(sapStoreModel.getMaktx());
			// 累计
			storeModel.setStoTodayStore(sapStoreModel.getSto1());
			storeModel.setStoOccupy(sapStoreModel.getLfimg());
			mapName = storeModel.getStoMmCode() + "-" + storeModel.getStoFac() + "-" + storeModel.getStoAddress();
			if (planMap.get(mapName) != null) {
				storeModel.setStoPlanOccupy(planMap.get(mapName).getProNum());
			}
			// 今日
			storeModel.setStoTodayOccupy(sapStoreModel.getLfimg1());
			storeModel.setStoTodayPlan(new BigDecimal(0));
			if (todayMap.get(mapName) != null) {
				storeModel.setStoTodayPlan(todayMap.get(mapName).getProNum());
			}
			storeModel.setStoTodayProduct(sapStoreModel.getJryj1());
			storeModel.setStoTodayResidue(storeModel.getStoTodayStore()
					.subtract(storeModel.getStoTodayPlan() == null ? BigDecimal.ZERO : storeModel.getStoTodayPlan())
					.subtract(storeModel.getStoOccupy() == null ? BigDecimal.ZERO : storeModel.getStoOccupy()));
			// 明日
			storeModel.setStoTomorowPlan(new BigDecimal(0));
			if (tomorowMap.get(mapName) != null) {
				storeModel.setStoTomorowPlan(tomorowMap.get(mapName).getProNum());
			}
			storeModel.setStoTomorowProduct(sapStoreModel.getJryj2());
			storeModel.setStoTomorowOccupy(sapStoreModel.getLfimg2());
			storeModel.setStoTomorowStore(storeModel.getStoTodayResidue().add(sapStoreModel.getJryj2()));
			storeModel.setStoTomorowResidue(storeModel.getStoTomorowStore().subtract(storeModel.getStoTomorowPlan()));
			// 后日
			storeModel.setStoAcquiredPlan(new BigDecimal(0));
			if (afterMap.get(mapName) != null) {
				storeModel.setStoAcquiredPlan(afterMap.get(mapName).getProNum());
			}
			storeModel.setStoAcquiredProduct(sapStoreModel.getJryj1());
			storeModel.setStoAcquiredOccupy(sapStoreModel.getLfimg3());
			storeModel.setStoAcquiredStore(storeModel.getStoTomorowResidue().add(sapStoreModel.getJryj3()));
			storeModel
					.setStoAcquiredResidue(storeModel.getStoAcquiredStore().subtract(storeModel.getStoAcquiredPlan()));

			storeDao.update(storeModel);

		}

		HttpResult httpResult = new HttpResult();
		httpResult.setMsg("刷新成功!");
		return httpResult;
	}

	// 根据日期获取物料分组排货计划求和
	private Map<String, PlanModel> groupPlan(String stoDate) {
		Map<String, PlanModel> planMap = new HashMap<String, PlanModel>();

		HashMap<String, Object> planHashMap = new HashMap<String, Object>();
		planHashMap.put("sendDateSum", stoDate);
		planHashMap.put("planServiceStatus", Global.YES + "");
		List<PlanModel> planModels = planDao.selectList(planHashMap);
		Map<String, List<PlanModel>> map = planModels.stream().collect(
				Collectors.groupingBy(d -> String.format("%s-%s-%s", d.getProCode(), d.getFacCode(), d.getStoCode())));
		map.forEach((name, plans) -> {
			BigDecimal sumNum = new BigDecimal(0);
			for (PlanModel plan : plans) {
				sumNum = sumNum.add(plan.getPlanPreNum());
				;
			}
			PlanModel planModel = new PlanModel();
			planModel.setProNum(sumNum);
			planMap.put(name, planModel);
		});

		return planMap;
	}

	// 根据物料分组排货计划求和排货计划占用总数
	private Map<String, PlanModel> groupPlanOccupy() {
		Map<String, PlanModel> planMap = new HashMap<String, PlanModel>();

		HashMap<String, Object> planHashMap = new HashMap<String, Object>();
		planHashMap.put("planSum", Global.YES + "");
//		planHashMap.put("status", Global.YES + "");
		List<PlanModel> planModels = planDao.selectList(planHashMap);
		Map<String, List<PlanModel>> map = planModels.stream().collect(
				Collectors.groupingBy(d -> String.format("%s-%s-%s", d.getProCode(), d.getFacCode(), d.getStoCode())));
		map.forEach((name, plans) -> {
			BigDecimal sumNum = new BigDecimal(0);
			for (PlanModel plan : plans) {
				sumNum = sumNum.add(plan.getPlanPreNum());
			}
			PlanModel planModel = new PlanModel();
			planModel.setProNum(sumNum);
			planMap.put(name, planModel);
		});

		return planMap;
	}

	/**
	 * 列表查询
	 *
	 * @param queryMap
	 * @return
	 */
	public HttpResult selectList(Map<String, Object> queryMap) {
		HttpResult httpResult = new HttpResult();
		EasyuiUtils.addPageNum(queryMap);
		EasyuiUtils.addFilter(queryMap);
		SysUser sysUser = SpringMvcUtils.getSysUser();
//		if (!sysUser.getSuperadmin().equals(Global.YES + "")) {
//			if (StringUtils.isNotNull(sysUser.getDatapermission())) {
//				queryMap.put("deptIds", sysUser.getDatapermission().split(","));
//			} else {
//				queryMap.put("createId", sysUser.getUserid());
//			}
//		}
		List<StoreModel> list = storeDao.selectList(queryMap);
		int count = storeDao.selectListCount(queryMap);
		httpResult.setRows(list);
		httpResult.setTotal(count);
		logger.info("selectList:{}", list);
		return httpResult;
	}

	/**
	 * 详情
	 * 
	 * @param
	 * @return
	 */
	public HttpResult selectInfor(String stoFac, String stoAddress, String stoMmCode) {
		HttpResult httpResult = new HttpResult();
		StoreModel storeModel = storeDao.load(stoFac, stoAddress, stoMmCode);
		httpResult.setData(storeModel);
		httpResult.setCode(HttpStatus.SUCCESS_CODE);
		return httpResult;
	}

	/**
	 * 保存
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult save(StoreModel storeModel) {
		if (storeModel == null) {
			return HttpResult.error("参数不能为空");
		}
		HttpResult httpResult = new HttpResult();
		int result = 0;
		if (!StringUtils.isNotNull(storeModel.getStoFac())) {
			storeModel.setStoFac(UUID.randomUUID().toString());
			result = storeDao.insert(storeModel);
		} else {
			result = storeDao.update(storeModel);
		}
		if (!StringUtils.isNotNull(storeModel.getStoAddress())) {
			storeModel.setStoAddress(UUID.randomUUID().toString());
			result = storeDao.insert(storeModel);
		} else {
			result = storeDao.update(storeModel);
		}
		if (!StringUtils.isNotNull(storeModel.getStoMmCode())) {
			storeModel.setStoMmCode(UUID.randomUUID().toString());
			result = storeDao.insert(storeModel);
		} else {
			result = storeDao.update(storeModel);
		}
		if (result > 0) {
			httpResult.setMsg(storeModel.getStatus().equals(Global.YES + "") ? "提交成功!" : "保存成功!");
			httpResult.setData(storeModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg(storeModel.getStatus().equals(Global.YES + "") ? "提交失败!" : "保存失败!");
		}
		return httpResult;
	}

	/**
	 * 提交
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult commit(StoreModel storeModel) {
		if (storeModel == null) {
			return HttpResult.error("参数不能为空");
		}
		storeModel.setStatus(Global.YES + "");
		HttpResult httpResult = new HttpResult();
		int result = 0;
		result = storeDao.update(storeModel);
		result = storeDao.update(storeModel);
		result = storeDao.update(storeModel);
		if (result > 0) {
			httpResult.setMsg(storeModel.getStatus().equals(Global.YES + "") ? "提交成功!" : "保存成功!");
			httpResult.setData(storeModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg(storeModel.getStatus().equals(Global.YES + "") ? "提交失败!" : "保存失败!");
		}
		return httpResult;
	}

	/**
	 * 删除
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult delete(String stoFac, String stoAddress, String stoMmCode) {
		if (!StringUtils.isNotNull(stoFac) || !StringUtils.isNotNull(stoAddress) || !StringUtils.isNotNull(stoMmCode)) {
			return HttpResult.error("参数不能为空");
		}
		StoreModel model = storeDao.load(stoFac, stoAddress, stoMmCode);
		if (model == null) {
			return HttpResult.error("无数据！");
		}
		if (!model.getStatus().equals(Global.NO + "")) {
			return HttpResult.error("非待提交状态，不可删除！");
		}
		HttpResult httpResult = new HttpResult();
		int result = storeDao.delete(stoFac, stoAddress, stoMmCode);
		if (result > 0) {
			httpResult.setMsg("删除成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 撤回
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult back(String stoFac, String stoAddress, String stoMmCode) {
		if (!StringUtils.isNotNull(stoFac) || !StringUtils.isNotNull(stoAddress) || !StringUtils.isNotNull(stoMmCode)) {
			return HttpResult.error("参数不能为空");
		}
		StoreModel model = storeDao.load(stoFac, stoAddress, stoMmCode);

		HttpResult httpResult = new HttpResult();
		model.setStatus(Global.NO + "");
		int result = storeDao.update(model);
		if (result > 0) {
			httpResult.setMsg("撤回成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 导出
	 * 
	 * @param queryMap
	 * @param response
	 */
	public void export(Map<String, Object> queryMap, HttpServletResponse response) {
		List<StoreModel> list = storeDao.selectList(queryMap);
		logger.info("export:{}", list);
		try {
			EasyExcel.write(response.getOutputStream(), StoreModel.class).sheet("模板").doWrite(list);
		} catch (IOException e) {
			logger.error("导出错误:{}", e.getMessage());
		}

	}
}
